package org.foreningsgatan.genetics.racers.visual;

import javax.swing.JFrame;

import static org.foreningsgatan.genetics.racers.Configuration.*;

import org.foreningsgatan.genetics.Generation;
import org.foreningsgatan.genetics.ProgramRunnable;
import org.foreningsgatan.genetics.racers.Actions;
import org.foreningsgatan.genetics.racers.Configuration;
import org.foreningsgatan.genetics.racers.RacingSimulation;
import org.foreningsgatan.genetics.racers.Sources;

public class GeneticRacers {
	private Generation<Sources, Actions> currentGeneration;
	private RacingSimulation simulation;
	private RacerComponent component;
	private JFrame frame;
	
	private void createGeneration() throws Exception {
		simulation = new RacingSimulation();

		currentGeneration = new Generation<Sources, Actions>(
				Configuration.sPopulation, simulation, 
				Sources.values(), Actions.values());
		currentGeneration.generateAndSimulateRandomPopulation(sThreads);
		
		for (int i = 0; i < sGenerations; i++) {
			System.out.println("");
			System.out.println("------------------------------");
			System.out.println(":: Generation " + i);
			System.out.println("------------------------------");
			currentGeneration = currentGeneration.next(sThreads);
		}
		
		simulation.resetAll();
	}
	
	private void initInterface() {
		component = new RacerComponent(simulation);
		
		frame = new JFrame();
		frame.getContentPane().add(component);
		frame.pack();
		frame.setVisible(true);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	private void runSimulation() {
		currentGeneration.getFittest().getRootNode().log(0);
		
		ProgramRunnable<Sources, Actions> simulationRunnable = 
			new ProgramRunnable<Sources, Actions>(
					currentGeneration.getFittest(), simulation, 1000 / sTargetFPS);
		
		simulationRunnable.addObserver(component);
		
		new Thread(simulationRunnable).start();
	}
	
	public GeneticRacers() throws Exception {
		createGeneration();
		initInterface();
		
		Thread.sleep(5000);
	}
	
	public static void main(String[] args) throws Exception {
		GeneticRacers racers = new GeneticRacers();
		racers.runSimulation();
	}
}
